package zunge.lbe1;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;

public class ScriptGen {
	
	String d_libFolder;
	public String getLibLinearFolder(){return d_libFolder+"liblinear/";}
	public String getRFolder(){return d_libFolder+"rscript/";}
	
	public ScriptGen(String d_libFolder){
		this.d_libFolder = d_libFolder;
	}
	
	public void splitScript(List<String> scripts, int coreCount, String label,
			String fileName, String scriptFolder, String tmpFolder) throws IOException{
		
		SignalObserver so = new SignalObserver(tmpFolder, label,coreCount, true);
		
		BufferedWriter bw = new BufferedWriter(new FileWriter(scriptFolder+fileName));
		
		int size = ((scripts.size()-1) / (coreCount))+1;
		
		for(int i = 0;i < coreCount;++i){
			String fileNamei = tmpFolder+fileName+"."+i+".sh";
			BufferedWriter bwi = new BufferedWriter(new FileWriter(fileNamei));
			for(int j = i*size;j < Math.min((i+1)*size, scripts.size());++j){
				if(j < scripts.size()){
					bwi.write(scripts.get(j)+"\n");
				}
			}
			bwi.write(so.genSignalGen(i)+"\n");
			bwi.close();
			bw.write("sh "+fileNamei+" &\n");
		}
		bw.close();
		
	}
	
	public static class SignalObserver{
		public static final String SIGNAL_SUFFIX = "signalobserver";
		public static final long WAIT_TIME = 10000; //milliseconds to scan
		String folder;
		String label;
		int scriptCount;
		
		public SignalObserver(
				String folder, String label, int scriptCount, boolean create){
			this.folder = folder;
			this.label = label;
			this.scriptCount = scriptCount;
			if(create){
				for(int i = 0;i < scriptCount;++i){
					new File(getSignalFile(i)).delete();
				}
			}
		}
		String getSignalFile(int scriptId){
			return folder+SIGNAL_SUFFIX+"_"+label+"_"+scriptId;
		}
		
		public String genSignalGen(int scriptId){
			return "touch "+getSignalFile(scriptId);
		}
		public void waitWhenFinish() throws InterruptedException{
			while(true){
				boolean finished = true;
				for(int i = 0;i < scriptCount;++i){
					if(!(new File(getSignalFile(i)).exists())){finished = false;}
				}
				if(finished){return;}
				Thread.sleep(WAIT_TIME);
			}
		}
		
	}
	
	
	
	/**
	 * LibLinear: L2-loss support vector classification (dual)
	 */
	public String genLibLinear(String f_train, String f_test, String f_model, String f_output, String f_log){
		return getLibLinearFolder()+"train -s 1 -q "+f_train+" "+f_model
				+" && "
				+getLibLinearFolder()+"predict "+f_test+" "+f_model+" "+f_output+" > "+f_log;
	}
	
	
	public String genRIrlba(int N, String fin_sparseMatrix, String fout_uf, String fout_mf, String fin_record, String fout_prediction, String fout_log){
		return "R --slave --args "
				+N+" "+fin_sparseMatrix+" "+fout_uf+" "+fout_mf+" "
				+fin_record+" "+fout_prediction+" "+fout_log+" "
				+"< "+getRFolder()+"irlba.R";
	}
	
	
	/** K=#clusters, N=#random start points,  C=#cores */
	public String genRKmeans(int K, int N, int C, 
			String fin_uf, String fout_center, String fout_label, String fout_size, String fout_log){
		
		return "R --slave --args"
				+" "+K+" "+N+" "+C
				+" "+fin_uf+" "+fout_center+" "+fout_label+" "+fout_size+" "+fout_log
				+" < "+getRFolder()+"kmeans.R";
	}
}
